
%%

%class GossipScanner
%function getToken
%type GossipToken
%yylexthrow Exception
%line
%column

%state STRING

%{
  StringBuilder sb;
%}

digit = [0-9]
letter = [a-zA-Z_]
alpha = {letter} | {digit}
space = [ \n\r\t]
comment = "/*"~"*/"

%%

<YYINITIAL> {

"class"    { return new GossipToken(GossipToken.CLASS, yyline, yycolumn); }
"var"    { return new GossipToken(GossipToken.VAR, yyline, yycolumn); }
"def"    { return new GossipToken(GossipToken.DEF, yyline, yycolumn); }
"new"    { return new GossipToken(GossipToken.NEW, yyline, yycolumn); }
"while"    { return new GossipToken(GossipToken.WHILE, yyline, yycolumn); }
"if"    { return new GossipToken(GossipToken.IF, yyline, yycolumn); }
"else"    { return new GossipToken(GossipToken.ELSE, yyline, yycolumn); }
"true"    { return new GossipToken(GossipToken.TRUE, yyline, yycolumn); }
"false"    { return new GossipToken(GossipToken.FALSE, yyline, yycolumn); }
"this"    { return new GossipToken(GossipToken.THIS, yyline, yycolumn); }
"null"    { return new GossipToken(GossipToken.NULL, yyline, yycolumn); }
"break"    { return new GossipToken(GossipToken.BREAK, yyline, yycolumn); }
"return"    { return new GossipToken(GossipToken.RETURN, yyline, yycolumn); }

{letter}{alpha}*	     { return new GossipToken(GossipToken.ID, yytext(), yyline, yycolumn); }

{digit}+("."{digit}+)?([eE]("+"|"-")?{digit}+)?  
   { return new GossipToken(GossipToken.NUMBER, Double.parseDouble(yytext()), yyline, yycolumn); }

"<="   { return new GossipToken(GossipToken.LEQ, yyline, yycolumn); }
".."   { return new GossipToken(GossipToken.CONCAT, yyline, yycolumn); }
"=="   { return new GossipToken(GossipToken.EQ, yyline, yycolumn); }
"&&"   { return new GossipToken(GossipToken.AND, yyline, yycolumn); }
"||"   { return new GossipToken(GossipToken.OR, yyline, yycolumn); }

"+" | "-" | "*" | "/" | "=" | "<" | "(" | ")" | ";" |
  "#" | "!" | "{" | "}" | "[" | "]" | "," | "." { return new GossipToken((int)yytext().charAt(0), 
    yyline, yycolumn); }

{space}    { }

{comment}    { }

[\"]     { yybegin(STRING); sb = new StringBuilder(); }

}

<STRING> {

"\\n"  { sb.append("\n"); }

"\\r"  { sb.append("\r"); }

"\\t"  { sb.append("\t"); }

"\\\""  { sb.append("\""); }

"\\\\"    { sb.append("\\"); }

[^\"\\\n]  { sb.append(yytext()); }

[\"]   { yybegin(YYINITIAL); return new GossipToken(GossipToken.STRING, sb.toString(), yyline, yycolumn); }

}

.  { throw new Exception("scanner error at line " + yyline + " column " + yycolumn + ", token: " + yytext()); }
